use std::sync::LazyLock;

use policy::{LinearDelayPolicy, RetirePolicy};

mod policy;

static POLICY: LazyLock<LinearDelayPolicy> =
    LazyLock::new(|| policy::LinearDelayPolicy::with_json("linear_delay_policy.json").unwrap());

pub fn retire_time(time: &str, tp: &str) -> String {
    println!("Input: {time}, {tp}");
    let msg = collect_message(time, tp);
    // 使用线性延迟退休策略
    let mut retire_result = POLICY.get_retire_result(msg).unwrap();
    // 年龄舍入到两位小数
    retire_result.retire_age = (retire_result.retire_age * 100.0).round() / 100.0;
    println!("Result: \n{:#?}", retire_result);

    format!(
        "{}-{:02},{},{}",
        retire_result.retire_time.0,
        retire_result.retire_time.1,
        retire_result.retire_age,
        retire_result.delayed_retire_months
    )
}

/// 获取相关信息.
/// time: 年-月.
/// tp: 要求输入串中不能出现与年龄无关的数字或多处数字; 要求性别关键词为单个字, 且仅由其最后一次出现决定.
fn collect_message(time: &str, tp: &str) -> policy::PersonMessage {
    let parts: Vec<u32> = time.split('-').map(|s| s.parse().unwrap()).collect();
    assert_eq!(parts.len(), 2, "仅支持\"年-月\"格式");

    let mut age = 0;
    let mut gender = None;

    for c in tp.chars() {
        if c.is_digit(10) {
            age = age * 10 + c.to_digit(10).unwrap();
        } else if let Some(g) = policy::Gender::string_to_gender(&c.to_string()) {
            gender = Some(g);
        }
    }

    let age = if age == 0 { None } else { Some(age) };

    policy::PersonMessage {
        birth_time: (parts[0], parts[1]),
        prev_retire_age: age,
        gender,
    }
}
